#include "baseserialcomm.h"

baseserialcomm::baseserialcomm(QSerialPort *parent) :QSerialPort(parent)
{
}

///
/// \brief baseserialcomm::listBaudRate
/// \param cbbBaud
///
void baseserialcomm::listBaudRate(QComboBox *cbbBaud)
{
    QMetaEnum mtaEnum = QMetaEnum::fromType<baseserialcomm::BaudRate>();
    QString tmp;
    for (int i = 0; i < mtaEnum.keyCount();i++){
        tmp = QString::number(mtaEnum.value(i));
        cbbBaud->addItem(tmp,mtaEnum.value(i));
        if(mtaEnum.value(i) == baseserialcomm::BaudRate::UnknownBaud){
            cbbBaud->removeItem(i);
        }
    }
    cbbBaud->setCurrentIndex(0);
}

void baseserialcomm::listDataBit(QComboBox *cbbDataBit)
{
    QString tmp;
    QMetaEnum mtaEnum = QMetaEnum::fromType<baseserialcomm::DataBits>();
    for (int i = 0; i<mtaEnum.keyCount();i++)
    {
        tmp = QString::number(mtaEnum.value(i));
        cbbDataBit->addItem(tmp,mtaEnum.value(i));
        if(mtaEnum.value(i) == baseserialcomm::DataBits::UnknownDataBits)
        {
            cbbDataBit->removeItem(i);
        }
    }
    cbbDataBit->setCurrentIndex(0);
}

void baseserialcomm::listPortNum(QComboBox *cbbPortNum){
    QStringList portList;
    qint32 len = 0;

    portList.clear();
    searchPort(portList);
    if (portList.empty() == false)
    {
        cbbPortNum->addItems(portList);
        foreach(const QString &item,portList)
        {
            if(len <item.toLocal8Bit().length())
            {
                len = item .toLocal8Bit().length();
            }
        }
        qint32  fontSize = cbbPortNum->font().pointSize();
        cbbPortNum->view()->setFixedWidth(len*fontSize *0.75);
    }
    else{
        QMessageBox::information(NULL,"无串口设备","没有搜索到串口设备",0,0);
    }
}

void baseserialcomm::listVerify(QComboBox *cbbVerify){
    QMetaEnum mtaEnum = QMetaEnum::fromType<baseserialcomm::Parity>();
    QString tmp;
    for (int i = 0; i<mtaEnum.keyCount();i++){
        cbbVerify->addItem(mtaEnum.key(i),mtaEnum.value(i));
        if (mtaEnum.value(i) == baseserialcomm::baseserialcomm::UnknownParity){
            cbbVerify->removeItem(i);
        }
    }
    cbbVerify->setCurrentIndex(0);
}

void baseserialcomm::listStopBit(QComboBox *cbbStopBit){
    QMetaEnum mtaEnum = QMetaEnum::fromType<baseserialcomm::StopBits>();
    QString tmp;
    for (int i = 0; i < mtaEnum.keyCount();i++){
        tmp = QString::number(mtaEnum.value(i));
        cbbStopBit->addItem(tmp,mtaEnum.value(i));
        if (mtaEnum.value(i) == baseserialcomm::baseserialcomm::UnknownStopBits){
            cbbStopBit->removeItem(i);
        }
    }
    cbbStopBit->setCurrentIndex(0);
}

void baseserialcomm::listTerminator(QComboBox *cbbTerminator){
    QMetaEnum mtaEnum = QMetaEnum::fromType<baseserialcomm::Terminator>();
    for (int i = 0; i < mtaEnum.keyCount();i++){
        cbbTerminator->addItem(mtaEnum.key(i),mtaEnum.value(i));
        if (mtaEnum.value(i) == baseserialcomm::Terminator::UnknownTerminator)
            cbbTerminator->removeItem(i);
    }
    cbbTerminator->setCurrentIndex(0);
}

void baseserialcomm::searchPort(QStringList &portList){
    portList.clear();
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){
        portList << info.portName() + " " + info.description();
    }
}

qint32 baseserialcomm::readData(QByteArray &rxBuffer){
    rxBuffer = this->readAll();
    if (rxBuffer.isEmpty()){
        return  0;
    }
    else{
        return rxBuffer.length();
    }
}

qint32 baseserialcomm::writtenData(QString txBuffer){
    QByteArray tmpBuffer = txBuffer.toLatin1();
    return this->write(tmpBuffer);
}


void baseserialcomm::insertTerminator(QByteArray &buffer, baseserialcomm::Terminator terminator){
    if(buffer.isEmpty())
        return;
    if (terminator != NONE){
        switch (terminator) {
        case CRLF_0x0D0A:
            buffer.append(CR_0x0D);
            buffer.append(LF_0xOA);
            break;
        case CR_0x0D:
            buffer.append(CR_0x0D);
            break;
        case LF_0xOA:
            buffer.append(LF_0xOA);
            break;
        default:break;
        }
    }
}


bool baseserialcomm::isHexString(QString src){
    bool isMathch = true;
    QRegExp regExp("[a-f0-9A-F]*");
    isMathch = regExp.exactMatch(src);
    return isMathch;
}

/**
 * @brief BaseSerialComm::verifyADD8 添加校验码 ADD8
 * @param buf
 * @return
 */
quint8 baseserialcomm::verifyADD8(QByteArray buf)
{
    quint8 retVal = 0;
    foreach(quint8 c, buf){
        retVal += c;
    }
    return retVal;
}


/**
 * @brief BaseSerialComm::verifyXOR8 添加校验码 XOR8
 * @param buf
 * @return
 */
quint8 baseserialcomm::verifyXOR8(QByteArray buf)
{
    quint8 retVal = 0;
    foreach(quint8 c, buf){
        retVal ^= c;
    }
    return retVal;
}

/**
 * @brief BaseSerialComm::verifyCRC16 添加校验码 Modbus CRC16
 * @param buf
 * @return CRC16
 */
quint16 baseserialcomm::verifyCRC16_Modbus(QByteArray buf)
{
    quint16 crc16;
    crc16 = crc16_modbus_calc((uint8_t *)buf.data(),buf.size());
    return crc16;
}

/**
 * @brief BaseSerialComm::verifyCRC16_CCITT  计算校验码 CCITT
 * @param buf
 * @return CRC16
 */
quint16 baseserialcomm::verifyCRC16_CCITT(QByteArray buf)
{
    quint16 crc16;
    crc16 = crc16_ccitt_calc((uint8_t *)buf.data(),buf.size());
    return crc16;
}
/**
 * @brief BaseSerialComm::verifyCRC32  计算校验码 CRC32
 * @param buf
 * @return CRC32
 */
quint32 baseserialcomm::verifyCRC32(QByteArray buf)
{
    quint32 crc32;
    crc32 = crc32_calc((uint8_t *)buf.data(),buf.size());
    return crc32;
}
/**
 * @brief BaseSerialComm::verifyLRC 计算校验码 LRC
 * @param buf
 * @return LRC-ASCII
 */
uint16_t baseserialcomm::verifyLRC(QByteArray buf)
{
    uint8_t uchLRC = 0;
    uint8_t tmp;
    uint16_t retVal;
    uchLRC = verifyADD8(buf);

    tmp = (uchLRC>>4);
    if( tmp <= 9 ){
        tmp += '0';
    }else{
        tmp += 'A';
    }
    retVal = tmp<<8;

    tmp = uchLRC&0x0F;
    if( tmp <= 9 )
    {
        tmp += '0';
    }
    else
    {
        tmp += 'A';
    }
    retVal |= tmp;
    return  ( retVal );
}
/**
 * @brief BaseSerialComm::verifyCrc8Ds18b20 校验码crc8 一般用于ds18b20
 * @param buf
 * @return CRC8
 */
uint8_t baseserialcomm::verifyCRC8_DS18B20(QByteArray buf)
{
    uint8_t crc8 = crc8_maxim_calc((uint8_t *)buf.data(), buf.size());
    return  crc8;
}
/**
 * @brief BaseSerialComm::verifyCrc16Usb 校验码crc16,一般用于usb校验
 * @param buf
 * @return CRC16 USB
 */
uint16_t baseserialcomm::verifyCRC16_USB(QByteArray buf)
{
    uint16_t crc16 = crc16_usb_calc((uint8_t *)buf.data(), buf.size());
    return crc16;
}
/**
 * @brief BaseSerialComm::verifyCrc16Ccitt_f 校验码crc16,一般用于ccitt false
 * @param buf
 * @return CRC16 CCITT False
 */
uint16_t baseserialcomm::verifyCRC16_CCITT_FALSE(QByteArray buf)
{
    uint16_t crc16 = crc16_ccitt_false_calc((uint8_t*)buf.data(), buf.size() );
    return crc16;
}





















